package com.guldan.thrall.web.controller;

import java.io.*;
import java.util.*;

import javax.servlet.http.HttpServletRequest;

import com.guldan.core.enums.CitizenUpdateTypeEn;
import com.guldan.core.enums.FileTypeEn;
import com.guldan.core.exception.BusinessException;
import com.guldan.jaina.dto.citizenbatchupdate.CitizenBatchUpdateDTO;
import com.guldan.jaina.dto.citizenbatchupdate.CitizenBatchUpdateSearchDTO;
import com.guldan.jaina.dto.progress.BarDTO;
import com.guldan.thrall.util.CitizenUpdateExcel;
import com.guldan.thrall.util.UserUtils;
import net.sf.json.JSONObject;
import net.sf.jxls.transformer.XLSTransformer;
import org.apache.poi.hssf.usermodel.*;
import org.jxls.common.Context;
import org.jxls.transform.poi.PoiTransformer;
import org.jxls.util.JxlsHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import com.alibaba.fastjson.JSON;
import com.guldan.core.controller.BaseController;
import com.guldan.core.dubbo.client.ResponseDTO;
import com.guldan.core.response.ResponseJson;
import com.guldan.core.search.Pagination;
import com.guldan.core.utils.DateUtil;
import com.guldan.jaina.dto.citizenfail.CitizenFailDTO;
import com.guldan.jaina.dto.citizenfail.CitizenFailSearchDTO;
import com.guldan.jaina.dto.citizeninfo.CitizenInfoDTO;
import com.guldan.jaina.dto.citizeninfo.CitizenInfoSearchDTO;
import com.guldan.jaina.dto.citizeninfo.CitizenUploadResultDTO;
import com.guldan.jaina.provider.ICitizenInfoProvider;
import com.guldan.core.constants.Constant;
import com.guldan.core.constants.XlsHeaderConstant;
import com.guldan.thrall.util.CitizenUploadExcel;

/**
 * Created by Silas.
 * Date: 2016/11/10
 * Time: 22:06
 */
@Controller
@RequestMapping("/citizen")
public class CitizenInfoController extends BaseController {

    protected Logger log = LoggerFactory.getLogger(getClass());
    @Autowired
    private ICitizenInfoProvider iCitizenInfoProvider;

    //获取单个居民信息
    @RequestMapping(value = "/get", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    CitizenInfoDTO get(@RequestBody CitizenInfoDTO dto) {
        ResponseDTO<CitizenInfoDTO> response = iCitizenInfoProvider.get(dto.getCitizenInfoId());
        return response.getData();
    }

    //新增/保存单个居民信息
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    CitizenInfoDTO save(@RequestBody CitizenInfoDTO dto) throws Exception {
        ResponseDTO<CitizenInfoDTO> response = iCitizenInfoProvider.save(dto);
        if (response.isSuccess())
            return response.getData();
        else {
            throw response.getException();
        }
    }

    //删除单个居民信息
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Boolean delete(@RequestBody CitizenInfoDTO dto) {
        ResponseDTO<Boolean> response = iCitizenInfoProvider.delete(dto.getCitizenInfoId());
        return response.getData();
    }

    //获取居民信息列表
    @RequestMapping(value = "/list", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Pagination<CitizenInfoDTO> list(@RequestBody CitizenInfoSearchDTO dto) {
        ResponseDTO<Pagination<CitizenInfoDTO>> response = iCitizenInfoProvider.list(dto);
        return response.getData();
    }

    //下载导入模板
    @RequestMapping(value = "/downTemplate ", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    String downTemplate() {
        String url = Constant.DOWNLOAD_URL_BASE + "?fileName=" + Constant.CITIZEN_XLS_TEMPLATE_NAME + "&type=" + FileTypeEn.template.getCode();
        return url;
    }

    //批量导入人员
    @RequestMapping(value = "/uploadCitizen", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    BarDTO uploadCitizen(HttpServletRequest request) throws Exception {
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
                request.getSession().getServletContext());
        String path = null;
        if (multipartResolver.isMultipart(request)) {
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            Iterator<String> iter = multiRequest.getFileNames();
            if (iter.hasNext()) {
                String fileName = iter.next();
                MultipartFile file = null;
                try {
                    file = multiRequest.getFile(fileName);
                } catch (Exception ex) {
                    log.info(ex.getMessage());
                    ex.printStackTrace();
                }
                if (file != null) {
                    String subDirectory = DateUtil.toLocaleString(new Date(), "yyyyMMdd");
                    String filePath = request.getRealPath("/") + Constant.ATTACHMENT_PATH_CITIZEN_UP + subDirectory;

                    File f = new File(filePath);
                    if (!f.exists())
                        f.mkdirs();
                    path = filePath + "/" + file.getOriginalFilename();
                    try {
                        file.transferTo(new File(path));
                    } catch (IllegalStateException | IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
            log.info("handling data packaging");
            //handling data packaging
            List<CitizenInfoDTO> list = null;
            CitizenUploadExcel excel = new CitizenUploadExcel();
            try {
                list = excel.readExcel(path);
                if (list != null && list.size() > 0) {
                    log.info(JSON.toJSONString(list));
                }
            } catch (IOException | BusinessException e) {
                // TODO Auto-generated catch block
                log.info(e.getMessage());
                e.printStackTrace();
                throw e;
            }
            ResponseDTO<BarDTO> response = iCitizenInfoProvider.uploadCitizen(list);
            if (response.isSuccess())
                return response.getData();
            else {
                throw response.getException();
            }
        }
        return null;
    }


    //批量导入人员相关接口
    //+++++++++++++++++++++++++++

    //获取导入失败人员列表
    @RequestMapping(value = "/failList", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Pagination<CitizenFailDTO> failList(@RequestBody CitizenFailSearchDTO dto) {
        ResponseDTO<Pagination<CitizenFailDTO>> response = iCitizenInfoProvider.failList(dto);
        return response.getData();
    }

    //获取单个导入失败人员信息
    @RequestMapping(value = "/getFail", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    CitizenFailDTO getFail(@RequestBody CitizenFailDTO dto) {
        ResponseDTO<CitizenFailDTO> response = iCitizenInfoProvider.getFail(dto.getId());
        return response.getData();
    }


    //批量导入人员相关接口
    //+++++++++++++++++++++++++++
    //获取居民信息列表
    @RequestMapping(value = "/uploadBatchList", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    List<CitizenFailDTO> uploadBatchList() {
        ResponseDTO<List<CitizenFailDTO>> response = iCitizenInfoProvider.uploadBatchList();
        return response.getData();
    }


    /**
     * 下载失败人员信息
     *
     * @param request
     * @param dto
     * @return
     */
    @RequestMapping(value = "/downFailList", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    String downFailList(HttpServletRequest request,
                        @RequestBody CitizenFailSearchDTO dto) {
        /*HttpServletRequest request,
        @RequestBody CitizenFailSearchDTO dto*/

//        CitizenFailSearchDTO dto = new CitizenFailSearchDTO();
//        dto.setCurrentPage(1);
//        dto.setBatchId("11111");
        dto.setCurrentPage(1);
        dto.setPerPage(1000000);
        ResponseDTO<String> response = iCitizenInfoProvider.failListForDownload(dto);

        logger.info("response.getData(): " + response.getData());

        Pagination<CitizenFailDTO> retData = (Pagination<CitizenFailDTO>) cacheService.getCache(response.getData());
        cacheService.removeCache(response.getData());
        List<CitizenFailDTO> data = retData.getList();

        logger.info("222222 size:" + data.size());

        List<String> headers = new ArrayList<String>();
        for (String header : XlsHeaderConstant.CITIZEN_FAIL_XLS_HEADERS) {
            headers.add(header);
        }

        //generating xls and return file url
        String fileName = dto.getBatchId().toLowerCase() + "_" + System.currentTimeMillis() + ".xls";   //用批次编号来作为文件名
        String url = "/" + Constant.ATTACHMENT_PATH_CITIZEN_DOWN + fileName;
        try {
            /*InputStream is = new FileInputStream(request.getRealPath("/") + Constant.CITIZEN_FAIL_XLS_TEMPLATE);
            OutputStream os = new FileOutputStream(request.getRealPath("/") + Constant.ATTACHMENT_PATH_CITIZEN_DOWN + fileName);
            Context context = PoiTransformer.createInitialContext();

            context.putVar("headers", headers);
            context.putVar("data", data);
            //context.putVar("props", "name,identNumber,areaName,projectName,year,subsidyCount");
            JxlsHelper.getInstance().processGridTemplateAtCell(is, os, context, "name,nameZw,nationName,degreeName,identTypeName,identNumber,bankName,bankNumber,areaName,householdRegisterNumber,master,relationName,householdNumber,citizenInfoTypeName,houseHoldTypeName,address,addressZw,telephone,failReason", "Sheet1!A1");
*/
//            Map<String, Object> context = new HashMap<>();
//            context.put("headers", headers);
//            context.put("data", data);
//            XLSTransformer former = new XLSTransformer();
//            String is = request.getRealPath("/") + Constant.CITIZEN_FAIL_XLS_TEMPLATE;
//            String os = request.getRealPath("/") + Constant.ATTACHMENT_PATH_CITIZEN_DOWN + fileName;
////            former.transformXLS(is, context, os);


        } catch (Exception ex) {
            ex.printStackTrace();
        }
        logger.info("register template url:" + url);


        /* 使用poi来生成execl */
        //创建book
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFCellStyle bodyStyle = wb.createCellStyle();
        bodyStyle.setWrapText(true);  //设置自动适应高度

        //创建sheet
        HSSFSheet sheet = wb.createSheet("sheet1");
        //设置各列的宽度
        sheet.setColumnWidth(0, 15 * 256); //第1列，15个字
        for (int i = 0; i < headers.size() - 1; i++) {
            sheet.setColumnWidth(i, 20 * 256);
        }
        sheet.setColumnWidth(headers.size() - 1, 100 * 256);

        //设置公共行数据
        //第一行提示文案
        HSSFRow row0 = sheet.createRow(0);
        HSSFCell cellNum00 = row0.createCell(0);
        cellNum00.setCellValue("失败列表");

        //设置表格标题行数据，第二行
        HSSFRow row1 = sheet.createRow(1);
        for (int i = 0; i < headers.size(); i++) {
            row1.createCell(i).setCellValue(headers.get(i));
        }

        //设置每行的数据
        for (int i = 2; i < data.size() + 2; i++) {

            logger.info("i: " + i);

            try {


                HSSFRow row = sheet.createRow(i);

                //基础列
                //姓名*
                HSSFCell cellNum0 = row.createCell(0);
                cellNum0.setCellValue(data.get(i - 2).getName());
                //姓名（藏）
                HSSFCell cellNum1 = row.createCell(1);
                cellNum1.setCellValue(data.get(i - 2).getNameZw());
                //民族*
                HSSFCell cellNum2 = row.createCell(2);
                cellNum2.setCellValue(data.get(i - 2).getNationName());
                //学历*
                HSSFCell cellNum3 = row.createCell(3);
                cellNum3.setCellValue(data.get(i - 2).getDegreeName());
                //证件类型*
                HSSFCell cellNum4 = row.createCell(4);
                cellNum4.setCellValue(data.get(i - 2).getIdentTypeName());
                //证件号码*
                HSSFCell cellNum5 = row.createCell(5);
                cellNum5.setCellValue(data.get(i - 2).getIdentNumber());
                //开户银行名称*
                HSSFCell cellNum6 = row.createCell(6);
                cellNum6.setCellValue(data.get(i - 2).getBankName());

                //开户银行卡号*
                HSSFCell cellNum7 = row.createCell(7);
                cellNum7.setCellValue(data.get(i - 2).getBankNumber());

                //用户归属行政区划*
                HSSFCell cellNum8 = row.createCell(8);
                cellNum8.setCellValue(data.get(i - 2).getAreaName());

                //户口簿编号*
                HSSFCell cellNum9 = row.createCell(9);
                cellNum9.setCellValue(data.get(i - 2).getHouseholdRegisterNumber());

                //是否户主*
                HSSFCell cellNum10 = row.createCell(10);
                cellNum10.setCellValue(data.get(i - 2).getMaster());

                //与户主关系*
                HSSFCell cellNum11 = row.createCell(11);
                cellNum11.setCellValue(data.get(i - 2).getRelationName());

                //户主证件号码*
                HSSFCell cellNum12 = row.createCell(12);
                cellNum12.setCellValue(data.get(i - 2).getHouseholdNumber());

                //人员分类*
                HSSFCell cellNum13 = row.createCell(13);
                cellNum13.setCellValue(data.get(i - 2).getCitizenInfoTypeName());

                //户口类别
                HSSFCell cellNum14 = row.createCell(14);
                cellNum14.setCellValue(data.get(i - 2).getIdentNumber());

                //家庭地址
                HSSFCell cellNum15 = row.createCell(15);
                cellNum15.setCellValue(data.get(i - 2).getAddress());

                //家庭住址（藏）
                HSSFCell cellNum16 = row.createCell(16);
                cellNum16.setCellValue(data.get(i - 2).getAddressZw());

                //电话号码
                HSSFCell cellNum17 = row.createCell(17);
                cellNum17.setCellValue(data.get(i - 2).getTelephone());

                //失败原因
                HSSFCell cellFail = row.createCell(18);
                cellFail.setCellStyle(bodyStyle);
                cellFail.setCellValue(new HSSFRichTextString(data.get(i - 2).getFailReason()));
            } catch (Exception ex) {
                logger.info("aaa " + JSONObject.fromObject(data.get(i - 2)).toString());
            }
        }
        String out = request.getRealPath("/") + Constant.ATTACHMENT_PATH_CITIZEN_DOWN + fileName;
        FileOutputStream fileOut = null;

        logger.info("11111111");

        try {
            fileOut = new FileOutputStream(out);
            wb.write(fileOut);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileOut.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return url;
    }


    //批量更新卡号
    //++++++++++++++++++++++++++++

    //下载更新卡号模版
    @RequestMapping(value = "/downBankTemplate ", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    String downBankTemplate() {
        String url = Constant.DOWNLOAD_URL_BASE + "?fileName=" + Constant.CITIZEN_BANK_XLS_TEMPLATE_NAME + "&type=" + FileTypeEn.template.getCode();
        return url;
    }

    //上传更新卡号模版
    @RequestMapping(value = "/uploadBankTemplate ", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    BarDTO uploadBankTemplate(HttpServletRequest request) throws Exception {
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
                request.getSession().getServletContext());
        String path = null;
        if (multipartResolver.isMultipart(request)) {
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            Iterator<String> iter = multiRequest.getFileNames();
            if (iter.hasNext()) {
                String fileName = iter.next();
                MultipartFile file = null;
                try {
                    file = multiRequest.getFile(fileName);
                } catch (Exception ex) {
                    log.info(ex.getMessage());
                    ex.printStackTrace();
                    throw new BusinessException("没有找到文件");
                }
                if (file != null) {
                    String subDirectory = DateUtil.toLocaleString(new Date(), "yyyyMMdd");
                    String filePath = request.getRealPath("/") + Constant.ATTACHMENT_PATH_CITIZEN_UPDATE_BANK_UP + subDirectory;

                    File f = new File(filePath);
                    if (!f.exists())
                        f.mkdirs();
                    path = filePath + "/" + file.getOriginalFilename();
                    try {
                        file.transferTo(new File(path));
                    } catch (IllegalStateException | IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        throw new BusinessException("没有找到文件");
                    }
                }
            }
            log.info("handling data packaging");
            //handling data packaging
            List<CitizenBatchUpdateDTO> list = null;
            CitizenUpdateExcel excel = new CitizenUpdateExcel(CitizenUpdateTypeEn.citizen_bank.getCode());
            try {
                list = excel.readExcel(path);
                if (list != null && list.size() > 0) {
                    log.info(JSON.toJSONString(list));
                }
            } catch (BusinessException e) {
                throw e;
            } catch (IOException e) {
                // TODO Auto-generated catch block
                log.info(e.getMessage());
                e.printStackTrace();
                throw e;
            }
            ResponseDTO<BarDTO> response = iCitizenInfoProvider.uploadBank(list);
            if (response.isSuccess())
                return response.getData();
            else {
                throw response.getException();
            }
        } else {
            throw new BusinessException("未知错误");
        }
    }

    //批量更新卡号，上传批次列表
    @RequestMapping(value = "/uploadBankBatchList ", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    List<CitizenBatchUpdateDTO> uploadBankBatchList() {
        CitizenBatchUpdateSearchDTO searchDTO = new CitizenBatchUpdateSearchDTO();
        searchDTO.setSuccess(false);
        searchDTO.setType(CitizenUpdateTypeEn.citizen_bank.getCode());
        ResponseDTO<List<CitizenBatchUpdateDTO>> response = iCitizenInfoProvider.uploadBatchList(searchDTO);
        return response.getData();
    }

    //批量更新卡号，查看失败记录列表
    @RequestMapping(value = "/uploadBankFailList ", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Pagination<CitizenBatchUpdateDTO> uploadBankFailList(@RequestBody CitizenBatchUpdateSearchDTO searchDTO) {
        searchDTO.setSuccess(false);
        searchDTO.setType(CitizenUpdateTypeEn.citizen_bank.getCode());
        ResponseDTO<Pagination<CitizenBatchUpdateDTO>> response = iCitizenInfoProvider.uploadFailList(searchDTO);
        return response.getData();
    }

    //批量更新卡号，下载失败列表
    @RequestMapping(value = "/downBankFailList ", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    String downBankFailList(HttpServletRequest request, @RequestBody CitizenBatchUpdateSearchDTO dto) throws BusinessException {
        dto.setSuccess(false);
        dto.setType(CitizenUpdateTypeEn.citizen_bank.getCode());
        ResponseDTO<List<CitizenBatchUpdateDTO>> response = iCitizenInfoProvider.downFailList(dto);
        List<CitizenBatchUpdateDTO> data = response.getData();

        List<String> headers = new ArrayList<String>();
        for (String header : XlsHeaderConstant.CITIZEN_UPDATE_BANK_XLS_HEADERS) {
            headers.add(header);
        }

        //generating xls and return file url
        String fileName = dto.getBatchId().toLowerCase() + ".xls";   //用批次编号来作为文件名
        String url = "/" + Constant.ATTACHMENT_PATH_CITIZEN_UPDATE_BANK_DOWN + fileName;
        try {
            /*InputStream is = new FileInputStream(request.getRealPath("/") + Constant.CITIZEN_UPDATE_XLS_TEMPLATE);
            OutputStream os = new FileOutputStream(request.getRealPath("/") + Constant.ATTACHMENT_PATH_CITIZEN_UPDATE_BANK_DOWN + fileName);
            Context context = PoiTransformer.createInitialContext();

            context.putVar("headers", headers);
            context.putVar("data", data);
            //context.putVar("props", "name,identNumber,areaName,projectName,year,subsidyCount");
            JxlsHelper.getInstance().processGridTemplateAtCell(is, os, context, "name,identNumber,bankName,bankNumber,failReason", "Sheet1!A1");
*/
            Map<String, Object> context = new HashMap<>();
            context.put("headers", headers);
            context.put("data", data);
            XLSTransformer former = new XLSTransformer();
            String is = request.getRealPath("/") + Constant.CITIZEN_BANK_FAIL_XLS_TEMPLATE;
            String os = request.getRealPath("/") + Constant.ATTACHMENT_PATH_CITIZEN_UPDATE_BANK_DOWN + fileName;
            former.transformXLS(is, context, os);


        } catch (Exception ex) {
            ex.printStackTrace();
            throw new BusinessException("失败，" + ex.getMessage());
        }
        logger.info("downBankFailList template url:" + url);
        return url;

    }

    //批量更新姓名
    //++++++++++++++++++++++++++++

    //下载更新姓名模版
    @RequestMapping(value = "/downNameTemplate ", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    String downNameTemplate() {
        String url = Constant.DOWNLOAD_URL_BASE + "?fileName=" + Constant.CITIZEN_NAME_XLS_TEMPLATE_NAME + "&type=" + FileTypeEn.template.getCode();
        return url;
    }


    //上传更新姓名模版
    @RequestMapping(value = "/uploadNameTemplate ", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    BarDTO uploadNameTemplate(HttpServletRequest request) throws Exception {
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
                request.getSession().getServletContext());
        String path = null;
        if (multipartResolver.isMultipart(request)) {
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            Iterator<String> iter = multiRequest.getFileNames();
            if (iter.hasNext()) {
                String fileName = iter.next();
                MultipartFile file = null;
                try {
                    file = multiRequest.getFile(fileName);
                } catch (Exception ex) {
                    log.info(ex.getMessage());
                    ex.printStackTrace();
                    throw new BusinessException("没有找到文件");
                }
                if (file != null) {
                    String subDirectory = DateUtil.toLocaleString(new Date(), "yyyyMMdd");
                    String filePath = request.getRealPath("/") + Constant.ATTACHMENT_PATH_CITIZEN_UPDATE_NAME_UP + subDirectory;

                    File f = new File(filePath);
                    if (!f.exists())
                        f.mkdirs();
                    path = filePath + "/" + file.getOriginalFilename();
                    try {
                        file.transferTo(new File(path));
                    } catch (IllegalStateException | IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        throw new BusinessException("没有找到文件");
                    }
                }
            }
            log.info("handling data packaging");
            //handling data packaging
            List<CitizenBatchUpdateDTO> list = null;
            CitizenUpdateExcel excel = new CitizenUpdateExcel(CitizenUpdateTypeEn.citizen_name.getCode());
            try {
                list = excel.readExcel(path);
                if (list != null && list.size() > 0) {
                    log.info(JSON.toJSONString(list));
                }
            } catch (BusinessException e) {
                // TODO Auto-generated catch block
                log.info(e.getMessage());
                e.printStackTrace();
                throw e;
            } catch (IOException e) {
                e.printStackTrace();
                throw e;
            }
            ResponseDTO<BarDTO> response = iCitizenInfoProvider.uploadName(list);
            if (response.isSuccess())
                return response.getData();
            else {
                throw response.getException();
            }
        } else {
            throw new BusinessException("未知错误");
        }
    }

    //批量更新姓名，上传批次列表
    @RequestMapping(value = "/uploadNameBatchList ", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    List<CitizenBatchUpdateDTO> uploadNameBatchList() {
        CitizenBatchUpdateSearchDTO searchDTO = new CitizenBatchUpdateSearchDTO();
        searchDTO.setSuccess(false);
        searchDTO.setType(CitizenUpdateTypeEn.citizen_name.getCode());
        ResponseDTO<List<CitizenBatchUpdateDTO>> response = iCitizenInfoProvider.uploadBatchList(searchDTO);
        return response.getData();
    }

    //批量更新姓名，查看失败记录列表
    @RequestMapping(value = "/uploadNameFailList ", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Pagination<CitizenBatchUpdateDTO> uploadNameFailList(@RequestBody CitizenBatchUpdateSearchDTO searchDTO) {
        searchDTO.setSuccess(false);
        searchDTO.setType(CitizenUpdateTypeEn.citizen_name.getCode());
        ResponseDTO<Pagination<CitizenBatchUpdateDTO>> response = iCitizenInfoProvider.uploadFailList(searchDTO);
        return response.getData();
    }

    //批量更新姓名，下载失败列表
    @RequestMapping(value = "/downNameFailList ", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    String downNameFailList(HttpServletRequest request, @RequestBody CitizenBatchUpdateSearchDTO dto) throws BusinessException {
        dto.setSuccess(false);
        dto.setType(CitizenUpdateTypeEn.citizen_name.getCode());
        ResponseDTO<List<CitizenBatchUpdateDTO>> response = iCitizenInfoProvider.downFailList(dto);
        List<CitizenBatchUpdateDTO> data = response.getData();

        List<String> headers = new ArrayList<String>();
        for (String header : XlsHeaderConstant.CITIZEN_UPDATE_NAME_XLS_HEADERS) {
            headers.add(header);
        }

        //generating xls and return file url
        String fileName = dto.getBatchId().toLowerCase() + ".xls";   //用批次编号来作为文件名
        String url = "/" + Constant.ATTACHMENT_PATH_CITIZEN_UPDATE_NAME_DOWN + fileName;
        try {

            /*InputStream is = new FileInputStream(request.getRealPath("/") + Constant.CITIZEN_UPDATE_XLS_TEMPLATE);
            OutputStream os = new FileOutputStream(request.getRealPath("/") + Constant.ATTACHMENT_PATH_CITIZEN_UPDATE_NAME_DOWN + fileName);
            Context context = PoiTransformer.createInitialContext();

            context.putVar("headers", headers);
            context.putVar("data", data);
            //context.putVar("props", "name,identNumber,areaName,projectName,year,subsidyCount");
            JxlsHelper.getInstance().processGridTemplateAtCell(is, os, context, "identNumber,oriName,name,failReason", "Sheet1!A1");
*/
            Map<String, Object> context = new HashMap<>();
            context.put("headers", headers);
            context.put("data", data);
            XLSTransformer former = new XLSTransformer();
            String is = request.getRealPath("/") + Constant.CITIZEN_NAME_FAIL_XLS_TEMPLATE;
            String os = request.getRealPath("/") + Constant.ATTACHMENT_PATH_CITIZEN_UPDATE_NAME_DOWN + fileName;
            former.transformXLS(is, context, os);


        } catch (Exception ex) {
            ex.printStackTrace();
            throw new BusinessException("失败，" + ex.getMessage());
        }
        logger.info("downNameFailList template url:" + url);
        return url;

    }


    //批量更新区划
    //++++++++++++++++++++++++++++

    //下载更新区划模版
    @RequestMapping(value = "/downAreaTemplate ", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    String downAreaTemplate() {
        String url = Constant.DOWNLOAD_URL_BASE + "?fileName=" + Constant.CITIZEN_AREA_XLS_TEMPLATE_NAME + "&type=" + FileTypeEn.template.getCode();
        return url;
    }


    //上传更新区划模版
    @RequestMapping(value = "/uploadAreaTemplate ", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    BarDTO uploadAreaTemplate(HttpServletRequest request) throws Exception {
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
                request.getSession().getServletContext());
        String path = null;
        if (multipartResolver.isMultipart(request)) {
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            Iterator<String> iter = multiRequest.getFileNames();
            if (iter.hasNext()) {
                String fileName = iter.next();
                MultipartFile file = null;
                try {
                    file = multiRequest.getFile(fileName);
                } catch (Exception ex) {
                    log.info(ex.getMessage());
                    ex.printStackTrace();
                    throw new BusinessException("没有找到文件");
                }
                if (file != null) {
                    String subDirectory = DateUtil.toLocaleString(new Date(), "yyyyMMdd");
                    String filePath = request.getRealPath("/") + Constant.ATTACHMENT_PATH_CITIZEN_UPDATE_AREA_UP + subDirectory;

                    File f = new File(filePath);
                    if (!f.exists())
                        f.mkdirs();
                    path = filePath + "/" + file.getOriginalFilename();
                    try {
                        file.transferTo(new File(path));
                    } catch (IllegalStateException | IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        throw new BusinessException("没有找到文件");
                    }
                }
            }
            log.info("handling data packaging");
            //handling data packaging
            List<CitizenBatchUpdateDTO> list = null;
            CitizenUpdateExcel excel = new CitizenUpdateExcel(CitizenUpdateTypeEn.citizen_area.getCode());
            try {
                list = excel.readExcel(path);
                if (list != null && list.size() > 0) {
                    log.info(JSON.toJSONString(list));
                }
            } catch (BusinessException e) {
                // TODO Auto-generated catch block
                log.info(e.getMessage());
                e.printStackTrace();
                throw e;
            } catch (IOException e) {
                e.printStackTrace();
                throw e;
            }
            ResponseDTO<BarDTO> response = iCitizenInfoProvider.uploadArea(list);
            if (response.isSuccess())
                return response.getData();
            else {
                throw response.getException();
            }
        } else {
            throw new BusinessException("未知错误");
        }
    }

    //批量更新区划，上传批次列表
    @RequestMapping(value = "/uploadAreaBatchList ", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    List<CitizenBatchUpdateDTO> uploadAreaBatchList() {
        CitizenBatchUpdateSearchDTO searchDTO = new CitizenBatchUpdateSearchDTO();
        searchDTO.setSuccess(false);
        searchDTO.setType(CitizenUpdateTypeEn.citizen_area.getCode());
        ResponseDTO<List<CitizenBatchUpdateDTO>> response = iCitizenInfoProvider.uploadBatchList(searchDTO);
        return response.getData();
    }

    //批量更新区划，查看失败记录列表
    @RequestMapping(value = "/uploadAreaFailList ", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Pagination<CitizenBatchUpdateDTO> uploadAreaFailList(@RequestBody CitizenBatchUpdateSearchDTO searchDTO) {
        searchDTO.setSuccess(false);
        searchDTO.setType(CitizenUpdateTypeEn.citizen_area.getCode());
        ResponseDTO<Pagination<CitizenBatchUpdateDTO>> response = iCitizenInfoProvider.uploadFailList(searchDTO);
        return response.getData();
    }

    //批量更新区划，下载失败列表
    @RequestMapping(value = "/downAreaFailList ", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    String downAreaFailList(HttpServletRequest request, @RequestBody CitizenBatchUpdateSearchDTO dto) throws BusinessException {
        dto.setSuccess(false);
        dto.setType(CitizenUpdateTypeEn.citizen_area.getCode());
        ResponseDTO<List<CitizenBatchUpdateDTO>> response = iCitizenInfoProvider.downFailList(dto);
        List<CitizenBatchUpdateDTO> data = response.getData();

        List<String> headers = new ArrayList<String>();
        for (String header : XlsHeaderConstant.CITIZEN_UPDATE_AREA_XLS_HEADERS) {
            headers.add(header);
        }

        //generating xls and return file url
        String fileName = dto.getBatchId().toLowerCase() + ".xls";   //用批次编号来作为文件名
        String url = "/" + Constant.ATTACHMENT_PATH_CITIZEN_UPDATE_AREA_DOWN + fileName;
        try {

            /*InputStream is = new FileInputStream(request.getRealPath("/") + Constant.CITIZEN_UPDATE_XLS_TEMPLATE);
            OutputStream os = new FileOutputStream(request.getRealPath("/") + Constant.ATTACHMENT_PATH_CITIZEN_UPDATE_AREA_DOWN + fileName);
*/
           /*
            Context context = PoiTransformer.createInitialContext();
            context.putVar("headers", headers);
            context.putVar("data", data);
            //context.putVar("props", "name,identNumber,areaName,projectName,year,subsidyCount");
            JxlsHelper.getInstance().processGridTemplateAtCell(is, os, context, "identNumber,newAreaCode,failReason", "Sheet1!A1");
        */


            Map<String, Object> context = new HashMap<>();
            context.put("headers", headers);
            context.put("data", data);
            XLSTransformer former = new XLSTransformer();
            String is = request.getRealPath("/") + Constant.CITIZEN_AREA_FAIL_XLS_TEMPLATE;
            String os = request.getRealPath("/") + Constant.ATTACHMENT_PATH_CITIZEN_UPDATE_AREA_DOWN + fileName;
            former.transformXLS(is, context, os);


        } catch (Exception ex) {
            ex.printStackTrace();
            throw new BusinessException("失败，" + ex.getMessage());
        }
        logger.info("downAreaFailList template url:" + url);
        return url;

    }

    //导出人员信息记录
    @RequestMapping(value = "/downCitizen ", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    String downCitizen(HttpServletRequest request, @RequestBody CitizenInfoSearchDTO dto) throws Exception {

        ResponseDTO<String> response = iCitizenInfoProvider.downCitizenList(dto);

        if (!response.isSuccess())
            throw response.getException();


        //generating xls and return file url
        String fileName = Long.valueOf(System.currentTimeMillis()) + ".xls";   //用批次编号来作为文件名
        String url = "/" + Constant.ATTACHMENT_PATH_CITIZEN_DOWN + fileName;
        try {

            /*InputStream is = new FileInputStream(request.getRealPath("/") + Constant.CITIZEN_UPDATE_XLS_TEMPLATE);
            OutputStream os = new FileOutputStream(request.getRealPath("/") + Constant.ATTACHMENT_PATH_CITIZEN_UPDATE_AREA_DOWN + fileName);
*/
           /*
            Context context = PoiTransformer.createInitialContext();
            context.putVar("headers", headers);
            context.putVar("data", data);
            //context.putVar("props", "name,identNumber,areaName,projectName,year,subsidyCount");
            JxlsHelper.getInstance().processGridTemplateAtCell(is, os, context, "identNumber,newAreaCode,failReason", "Sheet1!A1");
        */


            Map<String, Object> context = new HashMap<>();

            if (response.getData() != null)
                context.put("data", (List<CitizenInfoDTO>) cacheService.getCache(response.getData()));
            else
                context.put("data", new ArrayList<>());
            XLSTransformer former = new XLSTransformer();
            String is = request.getRealPath("/") + Constant.CITIZEN_DOWN_XLS_TEMPLATE;
            String os = request.getRealPath("/") + Constant.ATTACHMENT_PATH_CITIZEN_DOWN + fileName;
            former.transformXLS(is, context, os);


        } catch (Exception ex) {
            ex.printStackTrace();
            throw new BusinessException("失败，" + ex.getMessage());
        }
        logger.info("downCitizen file url:" + url);
        return url;
    }

}
